// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "DBManager/Repository/HDF5/Input/Design/DVSHAPRepository.h"

#include "DBManager/Repository/HDF5/Base/HDF5RepositoryMacro.h"

HDF5_REG_NO_SORT_REPOSITORY (DVSHAPRepository)

using namespace SG::DBManager::HDF5;
using namespace SG::DataStructure;
using namespace SG::DataStructure::FEM;
using namespace SG::DataStructure::Common;

// 构造函数实现
DVSHAPRepository::DVSHAPRepository (HDF5Database& database) : RepositoryBase (database)
{}

void DVSHAPRepository::InitialDatasetInfo ()
{
    RegisterTableInfo<NasMainStruct> ("/SG/INPUT/DESIGN/DVSHAP/IDENTITY", MainDataset);
    RegisterTableInfo<SubStructSFACTS> ("/SG/INPUT/DESIGN/DVSHAP/SFACTS", SubDataset_SFACTS);
}

/// @brief 写入配置
/// @param entity
SG::DataStructure::Common::Status DVSHAPRepository::Set (const SG::DataStructure::FEM::DVSHAPData& entity)
{
    NasMainStruct                IDENTITYData;
    std::vector<SubStructSFACTS> subDataVALUES;
    OwnToNastran (entity, IDENTITYData, subDataVALUES);

    CoverLocalData (this->GetDatasetInfo (MainDataset), IDENTITYData);
    CoverLocalData (this->GetDatasetInfo (SubDataset_SFACTS), 0, subDataVALUES);

    return SG::DataStructure::Common::Status::STATUS_Success;
}

/// @brief 获取配置
/// @return
SG::DataStructure::FEM::DVSHAPData DVSHAPRepository::Get ()
{
    NasMainStruct                IDENTITYData;
    std::vector<SubStructSFACTS> subDataVALUES;
    {
        // 获取数据集的路径和数据集对象
        HighFive::DataSet dataset = this->GetDataset (MainDataset);
        // 写出数据
        dataset.select ({ 0 }, { 1 }).read (IDENTITYData);
    }

    {
        // 获取数据集的路径和数据集对象
        HighFive::DataSet dataset = this->GetDataset (SubDataset_SFACTS);
        // 写出数据
        dataset.select ({ static_cast<UI64>(IDENTITYData.SFACTS_POS) }, { static_cast<UI64>(IDENTITYData.SFACTS_LEN) }).read (subDataVALUES);
    }

    MainStruct OwnIdent;

    NastranToOwn (IDENTITYData, subDataVALUES, OwnIdent);

    return OwnIdent;
}

void DVSHAPRepository::OwnToNastran (const MainStruct&                  OwnIdent,
                                     NasMainStruct& _OUT                IDENTITYData,
                                     std::vector<SubStructSFACTS>& _OUT subDataSFACTS,
                                     bool                               isSort)
{
    subDataSFACTS.clear ();
    // 获取已有数据条数，主要是放在主表的POS字段
    // 如果是重新排序的时候，Pos都是从0 开始的
    size_t countSFACTS = isSort ? 0 : this->GetDatasetInfo (SubDataset_SFACTS).GetRowCount ();

    // OwnIdent 代表咱们自己的数据结构
    // NasIdent 代表nastran的数据结构

    // 写入附表
    subDataSFACTS.insert (subDataSFACTS.end (), OwnIdent.m_SFACTSList.begin (), OwnIdent.m_SFACTSList.end ());

    const size_t lenSFACTS = OwnIdent.m_SFACTSList.size ();

    // 写入IDENTITY
    IDENTITYData.DOMAIN_ID = OwnIdent.m_domainId;

    IDENTITYData.SFACTS_POS = static_cast<I64> (countSFACTS);

    IDENTITYData.SFACTS_LEN = static_cast<I64> (lenSFACTS);
}

void DVSHAPRepository::NastranToOwn (NasMainStruct& IDENTITYData, std::vector<SubStructSFACTS>& subDataSFACTS, MainStruct& _OUT OwnIdent)
{
    // 代表初始的Index 位置,
    // 因为数据有可能是截取了附表的一部分，所有主表中根据POS找的时候需要对应一下，
    // 比如第一个主表数据中POS字段为10000， 附表的vector的数据
    // 就是从附表中的第10000个开始对应的 也就是Index==0的
    // const I64 index = IDENTITYData[0].POS;

    auto& NasIdent = IDENTITYData;

    OwnIdent.m_domainId = NasIdent.DOMAIN_ID;

    if (NasIdent.SFACTS_LEN != 0)
    {
        OwnIdent.m_SFACTSList.assign (subDataSFACTS.begin () + NasIdent.SFACTS_POS - IDENTITYData.SFACTS_POS,
                                      subDataSFACTS.begin () + NasIdent.SFACTS_POS + NasIdent.SFACTS_LEN - IDENTITYData.SFACTS_POS);
    }
}
